import parkIcon from '@/assets/png/park.png';
import positionIcon from '@/assets/png/positionfill.png';
import { DatePicker } from '@/components/AntdProxy';
import { formatSeconds } from '@/utils/format';
import mapHelper from '@/utils/mapHelper';
import { get } from '@/utils/request';
import { Button, Col, message, Row, Select, Space } from 'antd';
import dayjs from 'dayjs';
import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import AMap from '../AMap';
import { VehicleSelect } from '../CustomForm';
import './index.less';
// import moment from 'moment';
const { Option } = Select;

interface DrawMapProps {
  point?: {
    lat: number;
    lng: number;
  };
  points?: string;
  onPointChange?: (point: { lat: number; lng: number }) => void;
  onPolygonChange?: (points: string) => void;
  onAreaChange?: (area: number) => void;
}

const PointsAndAreaChoose: React.ForwardRefExoticComponent<
  DrawMapProps & React.RefAttributes<unknown>
> = forwardRef((props, ref) => {
  const { point, points, onPointChange, onPolygonChange, onAreaChange } = props;
  const map = useRef<any>();
  //   const AMap = useRef<any>();
  const marker = useRef<any>();
  const polygon = useRef<any>();
  const isStartDrawPolygon = useRef<boolean>(false);
  const [locationKeyWords, setLocationKeyWords] = useState<string | null>(null);
  const [currLocation, setCurrLocation] = useState<string>('');
  const [locationData, setLocationData] = useState<any[]>([]);
  const gpsLineRef = useRef<any>();

  const [vehicleId, setVehicleId] = useState<any>();
  const [time, setTime] = useState<any>([
    dayjs().startOf('day'),
    dayjs().endOf('day'),
  ]);

  // 加载标记点
  const loadMarker = (data: { name?: string; lat: number; lng: number }) => {
    const { lat, lng, name } = data;
    if (marker.current) {
      const [tLng, tLat] = mapHelper.wgs84togcj02(lng, lat);
      marker.current.setPosition(new map.current.aMap.LngLat(tLng, tLat));
      return;
    }
    marker.current = map.current.loadLabelMarker({
      lat,
      lng,
      title: name,
      image: positionIcon,
      addToLabelLayer: false,
    });
  };
  // 加载停车点
  const loadParkMarker = (data: {
    parkTime?: number;
    lat: number;
    lng: number;
  }) => {
    const { lat, lng, parkTime } = data;
    marker.current = map.current.loadLabelMarker({
      lat,
      lng,
      image: parkIcon,
      addToLabelLayer: true,
      showInfoWindow: true,
      infoWindowContent: `停车时长：${formatSeconds(parkTime)}`,
    });
  };
  const loadLine = (data: any[]) => {
    if (data.length) {
      gpsLineRef.current = map.current.loadLine(data, {
        showDir: true,
        strokeWeight: 4,
      });
    }
  };
  // 处理地图点击事件
  const handleMapClickEvent = (e: any) => {
    if (isStartDrawPolygon.current) return;

    const lnglat = e.lnglat;
    const [lng, lat] = mapHelper.gcj02towgs84(lnglat.lng, lnglat.lat);
    onPointChange?.({
      lat,
      lng,
    });
    loadMarker({
      lat,
      lng,
    });
  };

  // 初始化地图事件
  const initMapEvent = () => {
    map.current.initMapEventList([
      {
        eventName: 'complete',
        callback: () => {
          const el = document.querySelector('#amap');
          if (el) {
            (el as HTMLElement).style.cursor = 'pointer';
          }
        },
      },
      {
        eventName: 'mousemove',
        callback: (env: any) => {
          const { pixel } = env.originEvent;
          if (pixel && document.querySelector('.poi-container')) {
            // @ts-ignore
            document.querySelector('.poi-container').style.left = `${
              pixel.x + 10
            }px`;
            // @ts-ignore
            document.querySelector('.poi-container').style.top = `${pixel.y}px`;
          }
          const lnglat = env.lnglat;
          setCurrLocation(`${lnglat.lng}, ${lnglat.lat}`);
        },
      },
      {
        eventName: 'mouseout',
        callback: () => {
          setCurrLocation('');
        },
      },
    ]);
  };

  // 开始添加点
  const startAddPoint = () => {
    isStartDrawPolygon.current = false;
    map.current?.labelsLayer?.clear?.();
    if (marker.current) {
      map.current.remove(marker.current);
      marker.current = null;
    }
    map.current.mapInstance.on('click', handleMapClickEvent);
  };

  // 开始绘制多边形
  const startDrawPolygon = () => {
    isStartDrawPolygon.current = true;
    onPolygonChange?.('');
    onAreaChange?.(0);
    if (polygon.current) {
      map.current.remove(polygon.current);
      polygon.current = null;
    }
    map.current.enableDrawPolygon((e: any) => {
      const { points } = e;
      map.current.mouseTool.close();
      polygon.current = e.obj;
      onPolygonChange?.(points);
      onAreaChange?.(polygon.current.getArea() / 100000);
    });
  };
  const timeout = useRef<any>();
  let currentValue: string;
  // 搜索地址
  const fetchLocation = (
    value: string,
    callback: (data: { value: string; text: string }[]) => void,
  ) => {
    if (timeout.current) {
      clearTimeout(timeout.current);
      timeout.current = null;
      setLocationData([]);
    }
    currentValue = value;

    const fake = async () => {
      const { status, tips, info } = await get(
        '/poi',
        {
          key: 'a3c96444ba18b3c15c848caaed1edbcf',
          keywords: value,
        },
        { custom: true },
      );
      if (currentValue === value) {
        if (status === '1') {
          callback(tips);
        } else {
          message.error(info);
          callback([]);
        }
      }
    };
    timeout.current = setTimeout(fake, 500);
  };

  useEffect(() => {
    (async function () {
      if (!map.current) {
        const mapObj = new AMap({
          domId: 'amap',
        });
        await mapObj.load({
          plugins: ['AMap.PlaceSearch', 'AMap.MouseTool'],
        });
        map.current = mapObj;
        if (point?.lat && point?.lng) {
          marker.current = map.current.loadLabelMarker({
            ...point,
            image: positionIcon,
            addToLabelLayer: false,
          });
          map.current.setZoomAndCenter(12, { ...point });
        }
        // draw polygon
        if (points) {
          const pathArray = points.split(';').map((point) => {
            const [wgs84lng, wgs84lat] = point.split(',');
            return {
              lat: wgs84lat,
              lng: wgs84lng,
            };
          });
          polygon.current = map.current.loadPolygon(pathArray);
        }

        initMapEvent();
      }
    })();

    return () => {
      if (map.current) {
        map.current.destroy();
      }
    };
  }, []);
  useImperativeHandle(ref, () => {
    return {
      loadMarker,
    };
  });
  const queryGpsLit = async () => {
    if (vehicleId === undefined || vehicleId === null) {
      message.warning('请选择查询车辆');
      return;
    }
    if (!time || time.length <= 1) {
      message.warning('请选择查询时间段');
      return;
    }
    // formRef.current.validateFields().then(async () => {
    map.current.labelsLayer.clear();
    if (gpsLineRef.current) {
      map.current.remove(gpsLineRef.current);
    }
    // const { time, vehicleId } = formRef.current.getFieldsValue();
    let [startTime, endTime] = time;
    startTime = startTime.format('YYYY-MM-DD HH:mm:ss');
    endTime = endTime.format('YYYY-MM-DD HH:mm:ss');
    const { summary, gpslist } = await get(
      '/device/playback/vehicle/gps/list',
      {
        vehicleId,
        fromTime: startTime,
        toTime: endTime,
      },
    );
    loadLine(gpslist);
    (summary.stopPoints || []).forEach((item: any) => {
      const { lat, lng, timespans } = item;
      const hours = Math.floor(timespans / 3600);
      const minutes = Math.floor((timespans % 3600) / 60);
      if (hours > 0 || minutes > 5) {
        if (lat && lng) {
          loadParkMarker({
            parkTime: item.timespans,
            lat,
            lng,
          });
        }
      }
    });
    map.current.mapInstance.setFitView();
    // });
  };

  return (
    <>
      <Row gutter={5}>
        <Col span={8}>
          <VehicleSelect
            onChange={(value: any) => {
              setVehicleId(value);
            }}
          />
        </Col>
        <Col span={12}>
          <DatePicker.RangePicker
            showTime
            defaultValue={[dayjs().startOf('day'), dayjs().endOf('day')]}
            onChange={setTime}
            needConfirm={false}
          />
          {/* </Form.Item> */}
        </Col>
        <Col>
          <Button type="primary" onClick={queryGpsLit}>
            查询轨迹
          </Button>
        </Col>
      </Row>
      {/* </Form> */}
      <div className="draw-map-container">
        <div className="map-search">
          <Select
            size="small"
            style={{ width: '210px' }}
            showSearch
            value={locationKeyWords}
            defaultActiveFirstOption={false}
            filterOption={false}
            onSearch={async (newValue) => {
              if (newValue) {
                setLocationData([]);
                fetchLocation(newValue, setLocationData);
              } else {
                setLocationData([]);
              }
            }}
            onChange={(value: string) => {
              setLocationKeyWords(value);
            }}
            notFoundContent={'未找到相关地址'}
            placeholder="请输入地名查找"
            onSelect={(value: string) => {
              if (marker.current) {
                map.current.remove(marker.current);
                marker.current = null;
              }
              const latlng = value.split(',');
              map.current.setZoomAndCenter(13, {
                lat: latlng[1],
                lng: latlng[0],
              });
              map.current?.labelsLayer?.clear?.();
              marker.current = map.current.loadLabelMarker({
                lat: parseFloat(latlng[1]),
                lng: parseFloat(latlng[0]),
              });
              const [lng, lat] = mapHelper.gcj02towgs84(latlng[0], latlng[1]);
              onPointChange?.({
                lat,
                lng,
              });
            }}
          >
            {locationData
              .map((item: any) => {
                if (item.location.length) {
                  return <Option key={item.location}>{item.name}</Option>;
                } else {
                  return null;
                }
              })
              .filter((item) => item)}
          </Select>
        </div>
        <div className="map-tools">
          <Space>
            <Button size="small" onClick={startAddPoint}>
              标记地址
            </Button>
            <Button size="small" onClick={startDrawPolygon}>
              绘制区域
            </Button>
          </Space>
        </div>
        <div id="amap" style={{ width: '100%', height: '100%' }} />
        {currLocation && <div className="poi-container">{currLocation}</div>}
      </div>
    </>
  );
});

export default PointsAndAreaChoose;
